﻿#include "parameterbrowserwidget.h"
#include "ui_parameterbrowserwidget.h"
#include "parametertreemodel.h"

#include <QFileSystemModel>
#include <QStandardItemModel>
#include <QtDebug>
#include <QMessageBox>
#include <QInputDialog>
#include <QStandardPaths>
#include <QFileDialog>
#include <QListView>

#include <model/datamanager.h>

/**
 * @brief ParameterBrowserWidget::ParameterBrowserWidget
 * @details 构造参数表浏览器并初始化界面。
 * @param parent Qt 父窗口。
 */
ParameterBrowserWidget::ParameterBrowserWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::ParameterBrowserWidget)
{
    ui->setupUi(this);
    ui->splitter->setSizes({200, 800});
    setupModels();
}

/**
 * @brief ParameterBrowserWidget::~ParameterBrowserWidget
 * @details 释放界面资源。
 */
ParameterBrowserWidget::~ParameterBrowserWidget()
{
    delete ui;
}

/**
 * @brief ParameterBrowserWidget::on_btn_addTable_clicked
 * @details 复制或新建表格并在树中选中。
 */
void ParameterBrowserWidget::on_btn_addTable_clicked()
{
    QModelIndex currentIndex = ui->treeView->currentIndex();

    if (!currentIndex.isValid()) {
        QMessageBox::information(this, "提示", "请选择一个分类或一个要复制的表格。");
        return;
    }

    ParamTableKind internalType;
    TreeNode *node = m_parameterTreeModel->getNode(currentIndex);
    if (!node)
        return;

    internalType = node->categoryType;
    if (internalType == ParamTableKind::Default || internalType == ParamTableKind::Cal) {
        delete node;
        return;
    }

    OverviewItem newItem;
    newItem.id = -1; // 使用一个临时ID，表示“正在创建，尚未持久化”
    //复制表
    OverviewItem sourceOverview = m_parameterTreeModel->getOverview(currentIndex);
    newItem = DataManager::instance()->duplicateParameterTable(sourceOverview.id, sourceOverview.type);
    if (newItem.id > 0) {
        m_pendingSelectionName = newItem.name;
    } else {
        //复制表失败，创建空表
        int counter = 1;
        QString newTableName = "NewTable";
        QString originalName = newTableName;
        while (true) {
            bool isDuplicate = DataManager::instance()->overVivewNameExists(DataManager::instance()->getParameterTableOverviews(), newTableName);
            if (!isDuplicate) {
                break;
            }
            newTableName = originalName + "(" + QString::number(counter++) + ")";
        }

        newItem.type = internalType;
        newItem.name = newTableName;
        if (!DataManager::instance()->addParameterTable(newItem)) {
            QMessageBox::critical(this, "操作失败", "无法创建或复制表格。");
            qWarning() << "add ParameterTable failed！ itemName:" << newItem.name;
            return;
        }
    }
    m_parameterTreeModel->refresh();
    QModelIndex newIndex = m_parameterTreeModel->findIndexById(newItem.id, newItem.type);
    if (newIndex.isValid()) {
        ui->treeView->setCurrentIndex(newIndex);
        ui->treeView->scrollTo(newIndex, QAbstractItemView::PositionAtCenter);
        ui->treeView->expand(newIndex.parent());
    }
}

/**
 * @brief ParameterBrowserWidget::renameTreeItem
 * @details 开启当前树节点的重命名编辑。
 */
void ParameterBrowserWidget::renameTreeItem()
{
    QModelIndex index = ui->treeView->currentIndex();
    if (!index.isValid())
        return;
    ui->treeView->edit(index);
}

/**
 * @brief ParameterBrowserWidget::deleteTableRow
 * @details 删除当前树节点对应的行（预留）。
 */
void ParameterBrowserWidget::deleteTableRow()
{
    QModelIndex index = ui->treeView->currentIndex();
    if (!index.isValid())
        return;
}

/**
 * @brief ParameterBrowserWidget::setupModels
 * @details 初始化参数表模型与树模型并绑定信号。
 */
void ParameterBrowserWidget::setupModels()
{
    // 两个模型
    m_modelSimple = new ParameterTableModel(this);
    m_modelCal = new ParameterTableModel(this);
    m_modelCal->setKind(ParamTableKind::Cal);

    ui->tvSimple->setModel(m_modelSimple);
    ui->tvSimple->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

    ui->tvCal->setModel(m_modelCal);
    auto *hdr = ui->tvCal->horizontalHeader();
    hdr->setDefaultAlignment(Qt::AlignCenter);
    // 估算两行高度（按当前字体）
    const int twoLineH = hdr->fontMetrics().lineSpacing() * 2 + 20;
    hdr->setFixedHeight(twoLineH);
    // 宽度策略
    // hdr->setSectionResizeMode(QHeaderView::ResizeToContents);
    hdr->setSectionResizeMode(5, QHeaderView::ResizeToContents);
    hdr->setSectionResizeMode(6, QHeaderView::ResizeToContents);

    // 常规视图设置
    auto setupView = [](QTableView *v) {
        v->verticalHeader()->setVisible(false);
        v->setSelectionBehavior(QAbstractItemView::SelectRows);
        v->horizontalHeader()->setStretchLastSection(true);
        v->setAlternatingRowColors(true);
    };
    setupView(ui->tvSimple);
    setupView(ui->tvCal);
    ui->tvCal->setColumnHidden(0, true);
    ui->tvCal->setColumnHidden(9, true);
    ui->tvCal->setColumnHidden(10, true);
    ui->tvCal->setColumnHidden(11, true);
    ui->tvSimple->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked);
    ui->tvCal->setEditTriggers(QAbstractItemView::NoEditTriggers);

    m_parameterTreeModel = new ParameterTreeModel(this);
    ui->treeView->setModel(m_parameterTreeModel);
    m_parameterTreeModel->refresh();
    // 绑定模型到视图
    ui->treeView->setHeaderHidden(true);
    ui->treeView->setAlternatingRowColors(true); // 启用交替行颜色，方便阅读
    ui->treeView->setEditTriggers(QAbstractItemView::DoubleClicked);
    connect(ui->treeView->selectionModel(), &QItemSelectionModel::currentChanged,
            this, [this](const QModelIndex &current, const QModelIndex &) {
                onTreeViewPressed(current);
            });

    connect(DataManager::instance(), &DataManager::sig_parameterTablesChanged,
            this, &ParameterBrowserWidget::onParameterTablesChanged);
}

/**
 * @brief ParameterBrowserWidget::currentModel
 * @details 获取当前页面对应的数据模型。
 * @return 当前模型指针。
 */
ParameterTableModel *ParameterBrowserWidget::currentModel() const
{
    return (ui->stackedWidget->currentIndex() == 0) ? m_modelSimple : m_modelCal;
}
/**
 * @brief ParameterBrowserWidget::currentView
 * @details 获取当前页面对应的表格视图。
 * @return 当前视图指针。
 */
QTableView *ParameterBrowserWidget::currentView() const
{
    return (ui->stackedWidget->currentIndex() == 0) ? ui->tvSimple : ui->tvCal;
}

/**
 * @brief title2
 * @details 拼接字段与单位用于两行表头显示。
 * @param name 字段名称。
 * @param unit 单位字符串。
 * @return 拼接后的标题。
 */
static QString title2(const QString &name, const QString &unit)
{
    return unit.isEmpty() ? name : QString("%1\n(%2)").arg(name, unit);
}

// 加载 Cal 数据后，设置两行表头
/**
 * @brief ParameterBrowserWidget::applyCalTwoLineHeader
 * @details 根据校准数据设置双行表头。
 * @param rows 校准数据行集合。
 */
void ParameterBrowserWidget::applyCalTwoLineHeader(const QList<CalTableConfig> &rows)
{
    const QString uFreq = STR_UNIT_MHZ;
    const QString uPwr = STR_UNIT_DBM;
    const QString uImm = (!rows.isEmpty() ? rows.first().ImmunityLevelUnit : STR_UNIT_VM);
    const QString uLoss = STR_UNIT_DB;

    // 逐列设置“字段\n(单位)”，没有单位就只显示字段
    m_modelCal->setHeaderText(0, "ID");
    m_modelCal->setHeaderText(1, title2(tr("Frequency"), uFreq));
    m_modelCal->setHeaderText(2, title2(tr("Amplitude"), uPwr));
    m_modelCal->setHeaderText(3, title2(tr("FwdPower"), uPwr));
    m_modelCal->setHeaderText(4, title2(tr("RevPower"), uPwr));
    m_modelCal->setHeaderText(5, title2(tr("ImmunityLevel"), uImm));
    m_modelCal->setHeaderText(6, title2(tr("LimitImmunityLevel"), uImm));
    m_modelCal->setHeaderText(7, tr("SWR"));
    m_modelCal->setHeaderText(8, title2(tr("Loss"), uLoss));
    m_modelCal->setHeaderText(9, tr("CloseLoop"));
    m_modelCal->setHeaderText(10, tr("Info"));

    ui->tvCal->setColumnHidden(0, true);
    ui->tvCal->setColumnHidden(9, true);
    ui->tvCal->setColumnHidden(10, true);
    ui->tvCal->setColumnHidden(11, true);
}

/**
 * @brief ParameterBrowserWidget::setupTransducerHeaderCombos
 * @details 为换能器表设置单位下拉框。
 */
void ParameterBrowserWidget::setupTransducerHeaderCombos()
{
    // 确保当前模型是换能器模型 (在 Simple 页面且 Kind 是 Transducer)
    if (ui->stackedWidget->currentIndex() != 0 || m_modelSimple->kind() != ParamTableKind::Transducer) {
        return;
    }

    QTableView *tableView = ui->tvSimple; // 当前处理的是 Simple 页面的表格
    QHeaderView *headerView = tableView->horizontalHeader();

    // 创建源单位 ComboBox
    m_transSourceUnitHeaderCombo = new QComboBox(tableView); // 设置父对象为 tableView 有助于内存管理
    m_transSourceUnitHeaderCombo->addItem(STR_UNIT_DBM);
    m_transSourceUnitHeaderCombo->addItem("dB\u03BCV");
    auto view = new QListView(m_transSourceUnitHeaderCombo);
    view->setStyleSheet("QAbstractItemView::item { min-height: -1px; padding: -1px -1px; }");
    m_transSourceUnitHeaderCombo->setView(view);

    // 设置当前选中项为模型中存储的值
    QString currentSourceUnit = m_modelSimple->transducer().sourceUnit; // 从模型获取当前值
    int sourceIndex = m_transSourceUnitHeaderCombo->findText(currentSourceUnit);
    if (sourceIndex != -1) {
        m_transSourceUnitHeaderCombo->setCurrentIndex(sourceIndex);
    } else {
        // 如果模型中的值不在选项中，可以选择默认项或添加它
        m_transSourceUnitHeaderCombo->setCurrentIndex(0); // 默认选第一个
    }
    // 连接信号槽
    connect(m_transSourceUnitHeaderCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &ParameterBrowserWidget::onTransSourceUnitHeaderChanged);

    // 创建目标单位 ComboBox
    m_transTargetUnitHeaderCombo = new QComboBox(tableView);
    m_transTargetUnitHeaderCombo->addItem(STR_UNIT_VM);
    m_transTargetUnitHeaderCombo->addItem("dB\u03BCA");
    auto view2 = new QListView(m_transTargetUnitHeaderCombo);
    view2->setStyleSheet("QAbstractItemView::item { min-height: -1px; padding: -1px -1px; }");
    m_transTargetUnitHeaderCombo->setView(view2);
    // 设置当前选中项为模型中存储的值
    QString currentTargetUnit = m_modelSimple->transducer().targetUnit; // 从模型获取当前值
    int targetIndex = m_transTargetUnitHeaderCombo->findText(currentTargetUnit);
    if (targetIndex != -1) {
        m_transTargetUnitHeaderCombo->setCurrentIndex(targetIndex);
    } else {
        m_transTargetUnitHeaderCombo->setCurrentIndex(0); // 默认选第一个
    }
    // 连接信号槽
    connect(m_transTargetUnitHeaderCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &ParameterBrowserWidget::onTransTargetUnitHeaderChanged);

    QModelIndex sourceIndexModel = tableView->model()->headerData(0, Qt::Horizontal, Qt::DisplayRole).isValid() ? tableView->model()->index(0, 0) : QModelIndex(); // 获取第0列的索引
    QModelIndex targetIndexModel = tableView->model()->headerData(3, Qt::Horizontal, Qt::DisplayRole).isValid() ? tableView->model()->index(0, 3) : QModelIndex(); // 获取第3列的索引

    if (sourceIndexModel.isValid() || true) {
        tableView->setIndexWidget(tableView->model()->index(0, 0), m_transSourceUnitHeaderCombo);
    }
    if (targetIndexModel.isValid() || true) {
        tableView->setIndexWidget(tableView->model()->index(0, 3), m_transTargetUnitHeaderCombo);
    }
}

/**
 * @brief ParameterBrowserWidget::removeTransducerHeaderCombos
 * @details 移除换能器表头中的单位下拉框。
 */
void ParameterBrowserWidget::removeTransducerHeaderCombos()
{
    // 断开连接以避免在删除时触发信号
    if (m_transSourceUnitHeaderCombo) {
        disconnect(m_transSourceUnitHeaderCombo, nullptr, this, nullptr);
    }
    if (m_transTargetUnitHeaderCombo) {
        disconnect(m_transTargetUnitHeaderCombo, nullptr, this, nullptr);
    }

    // 从视图中移除并删除 ComboBox
    if (ui->tvSimple->indexWidget(ui->tvSimple->model()->index(0, 0))) {
        ui->tvSimple->setIndexWidget(ui->tvSimple->model()->index(0, 0), nullptr);
    }
    if (ui->tvSimple->indexWidget(ui->tvSimple->model()->index(0, 3))) {
        ui->tvSimple->setIndexWidget(ui->tvSimple->model()->index(0, 3), nullptr);
    }

    m_transSourceUnitHeaderCombo.clear();
    m_transTargetUnitHeaderCombo.clear();
}

/**
 * @brief ParameterBrowserWidget::on_btn_delTable_clicked
 * @details 删除选中的参数表并刷新界面。
 */
void ParameterBrowserWidget::on_btn_delTable_clicked()
{
    // 提交任何未结束的编辑（Tree/Table）
    if (QWidget *fw = QApplication::focusWidget())
        fw->clearFocus();

    const QModelIndex idx = ui->treeView->currentIndex();
    // 必须是叶子节点（有父节点）
    if (!idx.isValid() || !idx.parent().isValid()) {
        QMessageBox::information(this, "提示", "请先选中要删除的表。");
        return;
    }

    // 拿到该项概览
    OverviewItem ov = m_parameterTreeModel->getOverview(idx);
    if (ov.id <= 0) {
        QMessageBox::warning(this, "提示", "无效的表 ID。");
        return;
    }

    // 调用数据层删除
    bool ok = DataManager::instance()->removeParameterTable(ov.id, ov.type);
    if (!ok) {
        QMessageBox::critical(this, "删除失败", "删除数据库记录失败。");
        return;
    }

    // 若当前上下文正指向被删表，清空右侧视图和上下文
    if (m_ctx.valid && m_ctx.tableId == ov.id) {
        m_ctx = {}; // 重置上下文
        // 清空两个表模型的数据
        m_modelSimple->setKind(ParamTableKind::Attenuation); // 任意默认 kind
        m_modelSimple->setDataAtt(AttTableList {});
        m_modelCal->setDataCal(QList<CalTableConfig> {});
    }

    // 刷新树模型并尽量恢复到同一分类
    const int categoryRow = idx.parent().row();
    m_parameterTreeModel->refresh();
    QModelIndex parentAfter = m_parameterTreeModel->index(categoryRow, 0, QModelIndex());
    if (parentAfter.isValid()) {
        ui->treeView->setCurrentIndex(parentAfter);
        ui->treeView->expand(parentAfter);
    }

    QMessageBox::information(this, "成功", "已删除。");
}

/**
 * @brief pageIndexForKind
 * @details 根据表类型返回堆栈页索引。
 * @param k 参数表类型。
 * @return 对应页索引。
 */
static int pageIndexForKind(ParamTableKind k)
{
    return (k == ParamTableKind::Cal) ? 1 : 0;
}
/**
 * @brief ParameterBrowserWidget::onTreeViewPressed
 * @details 处理树节点选中并加载对应数据。
 * @param index 当前索引。
 */
void ParameterBrowserWidget::onTreeViewPressed(const QModelIndex &index)
{
    // 取节点信息
    if (!index.isValid())
        return;

    int categoryRow = -1;
    //分类节点处理
    if (!index.parent().isValid())
        categoryRow = index.row();

    if (categoryRow == -1)
        categoryRow = index.parent().row();

    ParamTableKind categoryType = static_cast<ParamTableKind>(categoryRow);
    bool st = (categoryType == ParamTableKind::Cal) ? false : true;
    ui->btn_addRow->setVisible(st);
    ui->btn_delRow->setVisible(st);
    ui->btn_addTable->setVisible(st);
    ui->btn_inputTable->setVisible(st);
    //    ui->btn_outputTable->setVisible(st);
    if (!index.parent().isValid())
        return;

    OverviewItem ov = m_parameterTreeModel->getOverview(index);
    m_ctx.kind = ov.type;
    m_ctx.tableId = ov.id;
    m_ctx.typeStr = DataManager::instance()->getParamTableEnumString(ov.type);
    m_ctx.valid = true;

    const int page = pageIndexForKind(m_ctx.kind);
    if (ui->stackedWidget->currentIndex() != page)
        ui->stackedWidget->setCurrentIndex(page);

    // 懒加载/按需加载
    if (page == 0) {
        m_modelSimple->setKind(m_ctx.kind);
        if (ov.id > 0) {
            switch (m_ctx.kind) {
            case ParamTableKind::Attenuation: {
                AttTableList ttttt = DataManager::instance()->getAttTable(ov.id);
                m_modelSimple->setDataAtt(ttttt);
                m_modelSimple->applyNonCalHeaders(STR_UNIT_MHZ, STR_UNIT_DB); // Frequency(MHz), Att(dB)
                break;
            }
            case ParamTableKind::Transducer: {
                auto t = DataManager::instance()->getTransducerTable(ov.id);
                if (t.factorsList.isEmpty()) {
                    t.factorsList.append(FactorsConfig());
                }
                m_modelSimple->setDataTransducer(t);
                m_modelSimple->applyNonCalHeaders(t.xUnit, t.yUnit);
                setupTransducerHeaderCombos();
                break;
            }
            case ParamTableKind::LimitLine: {
                auto t = DataManager::instance()->getLimitLineTable(ov.id);
                m_modelSimple->setDataLimitLine(t);
                // m_modelSimple->applyNonCalHeaders(STR_UNIT_MHZ, t.yUnit);
                //--251029 不再显示单位，临时解决手动创建表时无法区分V/m和dBuA单位的问题
                m_modelSimple->applyNonCalHeaders(STR_UNIT_MHZ, "");
                break;
            }
            case ParamTableKind::Frequency:
                m_modelSimple->setDataFreq(DataManager::instance()->getFreqTable(ov.id));
                m_modelSimple->applyNonCalHeaders(STR_UNIT_MHZ, "");
                break;
            default:
                break;
            }
        } else {
            // 新建：给空数据模型，让TabView显示正确的列
            switch (m_ctx.kind) {
            case ParamTableKind::Attenuation:
                m_modelSimple->setDataAtt(AttTableList {});
                m_modelSimple->applyNonCalHeaders(STR_UNIT_MHZ, STR_UNIT_DB);
                break;
            case ParamTableKind::Transducer:
                m_modelSimple->setDataTransducer(TransducerTableList {});
                m_modelSimple->applyNonCalHeaders(STR_UNIT_MHZ, STR_UNIT_DBM); // 默认
                setupTransducerHeaderCombos();
                break;
            case ParamTableKind::LimitLine:
                m_modelSimple->setDataLimitLine(LimitLineList {});
                m_modelSimple->applyNonCalHeaders(STR_UNIT_MHZ, STR_UNIT_VM);
                break;
            case ParamTableKind::Frequency:
                m_modelSimple->setDataFreq(QList<FreqTableConfig> {});
                m_modelSimple->applyNonCalHeaders(STR_UNIT_MHZ, "");
                break;
            default:
                break;
            }
        }
    } else {
        removeTransducerHeaderCombos();
        auto rows = ov.id > 0 ? DataManager::instance()->getCalibrationTable(ov.id)
                              : QList<CalTableConfig> {};
        m_modelCal->setDataCal(rows);
        applyCalTwoLineHeader(rows);
    }
}

/**
 * @brief ParameterBrowserWidget::on_btn_save_clicked
 * @details 保存当前表格内容到数据库。
 */
void ParameterBrowserWidget::on_btn_save_clicked()
{
    if (!m_ctx.valid) {
        QMessageBox::warning(this, "提示", "未选中任何表");
        return;
    }
    QString newName = ui->treeView->currentIndex().data(Qt::DisplayRole).toString().trimmed();

    bool ok = false;
    if (ui->stackedWidget->currentIndex() == 0) {
        switch (m_modelSimple->kind()) {
        case ParamTableKind::Attenuation:
            ok = DataManager::instance()->saveAttTable(m_ctx.tableId, newName, m_modelSimple->att());
            break;
        case ParamTableKind::Transducer:
            ok = DataManager::instance()->saveTransducerTable(m_ctx.tableId, newName, m_modelSimple->transducer());
            break;
        case ParamTableKind::LimitLine:
            ok = DataManager::instance()->saveLimitLineTable(m_ctx.tableId, newName, m_modelSimple->limitLine());
            break;
        case ParamTableKind::Frequency:
            ok = DataManager::instance()->saveFreqTable(m_ctx.tableId, newName, m_modelSimple->freq());
            break;
        default:
            break;
        }
    } else {
        ok = DataManager::instance()->saveCalibrationTable(m_ctx.tableId, newName, m_modelCal->cal());
    }

    QMessageBox::information(this, ok ? "成功" : "失败", ok ? "保存完成" : "保存失败");
}

/**
 * @brief ParameterBrowserWidget::on_btn_addRow_clicked
 * @details 在当前表格中插入一行数据。
 */
void ParameterBrowserWidget::on_btn_addRow_clicked()
{
    auto mdl = currentModel();
    auto tv = currentView();
    if (!mdl || !m_ctx.valid)
        return;

    int insertRow = tv->currentIndex().isValid()
                        ? tv->currentIndex().row() + 1
                        : mdl->rowCount();

    mdl->insertRow(insertRow);

    // 选中新插入行并滚动可见
    const QModelIndex idx = mdl->index(insertRow, 0);
    tv->setCurrentIndex(idx);
    tv->scrollTo(idx);
}

/**
 * @brief ParameterBrowserWidget::on_btn_delRow_clicked
 * @details 删除当前表格选中的行。
 */
void ParameterBrowserWidget::on_btn_delRow_clicked()
{
    auto mdl = currentModel();
    auto tv = currentView();
    if (!mdl || !m_ctx.valid || !tv->selectionModel())
        return;

    auto rows = tv->selectionModel()->selectedRows(); // 选中整行
    if (rows.isEmpty())
        return;
    const bool isTransducerTable = (mdl == m_modelSimple) && (m_ctx.kind == ParamTableKind::Transducer);
    if (isTransducerTable) {
        bool isDeletingFirstRow = std::any_of(rows.constBegin(), rows.constEnd(), [](const QModelIndex &idx) { return idx.row() == 0; });
        if (isDeletingFirstRow)
            return;
    }

    std::sort(rows.begin(), rows.end(),
              [](const QModelIndex &a, const QModelIndex &b) { return a.row() > b.row(); });

    for (const auto &ix : rows) {
        mdl->removeRow(ix.row());
    }
}

/**
 * @brief ParameterBrowserWidget::onParameterTablesChanged
 * @details 数据源发生变化时刷新树并恢复选择。
 */
void ParameterBrowserWidget::onParameterTablesChanged()
{
    int lastSelectedCategoryRow = -1; // -1 表示没有选中分类
    m_lastSelectedTableId = -1;       // 重置表格ID记录

    QModelIndex currentIndex = ui->treeView->currentIndex();
    if (currentIndex.isValid()) {
        if (currentIndex.parent().isValid()) { // 确保是子节点
            OverviewItem ov = m_parameterTreeModel->getOverview(currentIndex);
            if (ov.id > 0) {
                m_lastSelectedTableId = ov.id;
                m_lastSelectedKind = ov.type;
            }
        } else {
            // m_lastSelectedTableId = -1; // 如果没有选中或选中了分类，则重置
            lastSelectedCategoryRow = currentIndex.row();
        }
    }

    m_parameterTreeModel->refresh();
    QModelIndex indexToSelect;

    if (m_lastSelectedTableId > 0)
        indexToSelect = m_parameterTreeModel->findIndexById(m_lastSelectedTableId, m_lastSelectedKind);
    else if (lastSelectedCategoryRow != -1) {
        //处理之前选中了分类的情况
        QModelIndex categoryIndex = m_parameterTreeModel->index(lastSelectedCategoryRow, 0, QModelIndex());
        if (categoryIndex.isValid() && m_parameterTreeModel->hasChildren(categoryIndex)) {
            // 获取该分类下的子节点数量
            int childCount = m_parameterTreeModel->rowCount(categoryIndex);
            // 选中最后一个子节点
            indexToSelect = m_parameterTreeModel->index(childCount - 1, 0, categoryIndex);
        }
    }
    if (indexToSelect.isValid()) {
        // 如果找到了，就选中它、滚动到它，并展开它的父节点
        ui->treeView->setCurrentIndex(indexToSelect);
        ui->treeView->scrollTo(indexToSelect, QAbstractItemView::PositionAtCenter);
        ui->treeView->expand(indexToSelect.parent());
    }
}

/**
 * @brief ParameterBrowserWidget::on_btn_outputTable_clicked
 * @details 导出当前表格为 CSV 文件。
 */
void ParameterBrowserWidget::on_btn_outputTable_clicked()
{
    //  检查是否选中了一个有效的表格
    if (!m_ctx.valid || m_ctx.tableId <= 0) {
        QMessageBox::information(this, tr("提示"), tr("请先在左侧树中选择一个要导出的表格。"));
        return;
    }

    ParameterTableModel *model = currentModel();
    if (!model || model->rowCount() == 0) {
        QMessageBox::information(this, tr("提示"), tr("当前表格没有数据可以导出。"));
        return;
    }

    //  弹出文件保存对话框
    QString currentTableName = ui->treeView->currentIndex().data(Qt::DisplayRole).toString();
    QString defaultFileName = currentTableName + ".csv";
    QString documentsPath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);

    QString filePath = QFileDialog::getSaveFileName(this, tr("导出表格"), documentsPath + "/" + defaultFileName,
                                                    tr("CSV 文件 (*.csv);;所有文件 (*.*)"));

    if (filePath.isEmpty())
        return;

    //  打开文件并写入数据
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QMessageBox::critical(this, tr("错误"), tr("无法打开文件进行写入：\n%1").arg(file.errorString()));
        return;
    }

    QTextStream out(&file);
    out.setCodec("UTF-8"); // 使用UTF-8编码
    for (int row = 0; row < model->rowCount(); ++row) {
        QStringList rowData;
        for (int col = 0; col < model->columnCount(); ++col) {
            QModelIndex idx = model->index(row, col);
            QVariant data;

            if (model->flags(idx) & Qt::ItemIsUserCheckable) {
                data = model->data(idx, Qt::CheckStateRole).toInt() == Qt::Checked ? "true" : "false";
            } else {
                data = model->data(idx, Qt::DisplayRole);
            }

            QString cellData = data.toString();

            // 对包含逗号或引号的数据进行CSV转义
            if (cellData.contains(',') || cellData.contains('"') || cellData.contains('\n')) {
                cellData.replace('"', "\"\""); // 双引号转义
                rowData << QString("\"%1\"").arg(cellData);
            } else {
                rowData << cellData;
            }
        }
        out << rowData.join(',') << "\n";
    }

    file.close();
    QMessageBox::information(this, tr("成功"), tr("表格已成功导出到：\n%1").arg(filePath));
}

/**
 * @brief ParameterBrowserWidget::on_btn_inputTable_clicked
 * @details 从 CSV 文件导入新表格。
 */
void ParameterBrowserWidget::on_btn_inputTable_clicked()
{
    //  检查 TreeView 中的选中项以确定目标分类
    QModelIndex currentIndex = ui->treeView->currentIndex();
    if (!currentIndex.isValid()) {
        QMessageBox::information(this, tr("提示"), tr("请先在左侧树中选择一个分类，以确定新表格的类型。"));
        return;
    }

    ParamTableKind targetKind;
    // 如果选中了子节点（一个具体的表）
    if (currentIndex.parent().isValid()) {
        targetKind = static_cast<ParamTableKind>(currentIndex.parent().row());
    } else {
        targetKind = static_cast<ParamTableKind>(currentIndex.row());
    }

    if (targetKind == ParamTableKind::Default) {
        QMessageBox::warning(this, tr("操作无效"), tr("不能向此分类导入表格。"));
        return;
    }

    QString documentsPath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
    QString filePath = QFileDialog::getOpenFileName(this,
                                                    tr("导入表格"),
                                                    documentsPath,
                                                    tr("CSV 文件 (*.csv);;所有文件 (*.*)"));

    if (filePath.isEmpty())
        return; // 用户取消

    QFileInfo fileInfo(filePath);
    QString newTableName = fileInfo.baseName();

    int counter = 1;
    QString originalName = newTableName;
    const auto &overviews = DataManager::instance()->getParameterTableOverviews();
    while (DataManager::instance()->overVivewNameExists(overviews, newTableName)) {
        newTableName = originalName + "(" + QString::number(counter++) + ")";
    }

    QList<QStringList> csvData;
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        return;
    }
    QTextStream in(&file);
    in.setCodec("UTF-8");
    while (!in.atEnd()) {
        csvData.append(in.readLine().split(','));
    }
    file.close();

    if (csvData.isEmpty()) {
        QMessageBox::warning(this, tr("导入失败"), tr("文件为空或格式错误。"));
        return;
    }

    QStringList header = csvData.takeFirst();
    bool saveOk = false;
    OverviewItem newItem;
    newItem.id = -1;
    switch (targetKind) {
    case ParamTableKind::Cal:
        break;
    case ParamTableKind::Attenuation: {
        if (header.size() < 2) {
            QMessageBox::warning(this, tr("错误"), tr("文件数据与目标类型不匹配。"));
            return;
        }
        AttTableList attList;
        for (const auto &fields : csvData) {
            if (fields.size() < 2)
                continue;
            AttTableConfig row;
            row.Freq = fields[0].toDouble() * 1e6;
            row.Att = fields[1].toDouble();
            attList.attList.append(row);
        }
        newItem.name = newTableName;
        newItem.type = ParamTableKind::Attenuation;
        m_pendingSelectionName = newTableName;
        if (!DataManager::instance()->addParameterTable(newItem)) {
            qWarning() << "add ParameterTable failed！ itemName:" << newItem.name;
            break;
        }
        saveOk = DataManager::instance()->saveAttTable(newItem.id, newTableName, attList);
        break;
    }
    case ParamTableKind::Transducer: {
        if (header.size() < 4) {
            QMessageBox::warning(this, tr("错误"), tr("文件数据与目标类型不匹配。"));
            return;
        }
        TransducerTableList list;
        if (!csvData.isEmpty() && csvData.first().size() >= 4) {
            // 假设所有行的单位都相同，从第一行获取
            list.sourceUnit = csvData.first().first(); // 第一列
            list.targetUnit = csvData.first().last();  // 最后一列
        }

        for (const auto &fields : csvData) {
            if (fields.size() < 4)
                continue;
            FactorsConfig row;
            row.Freq = fields[1].toDouble() * 1e6;
            row.Factors = fields[2].toDouble();
            list.factorsList.append(row);
        }
        newItem.name = newTableName;
        newItem.type = ParamTableKind::Transducer;
        m_pendingSelectionName = newTableName;
        if (!DataManager::instance()->addParameterTable(newItem)) {
            qWarning() << "add ParameterTable failed！ itemName:" << newItem.name;
            break;
        }
        saveOk = DataManager::instance()->saveTransducerTable(newItem.id, newTableName, list);
        break;
    }
    case ParamTableKind::LimitLine: {
        if (header.size() < 2) {
            QMessageBox::warning(this, tr("错误"), tr("文件数据与目标类型不匹配。"));
            return;
        }
        LimitLineList list;
        for (const auto &fields : csvData) {
            if (fields.size() < 2)
                continue;
            LimitLineConfig row;
            row.Freq = fields[0].toDouble() * 1e6;
            row.Limit = fields[1].toDouble();
            list.limitList.append(row);
        }
        newItem.name = newTableName;
        newItem.type = ParamTableKind::LimitLine;
        m_pendingSelectionName = newTableName;
        if (!DataManager::instance()->addParameterTable(newItem)) {
            qWarning() << "add ParameterTable failed！ itemName:" << newItem.name;
            break;
        }
        saveOk = DataManager::instance()->saveLimitLineTable(newItem.id, newTableName, list);
        break;
    }
    case ParamTableKind::Frequency: {
        if (header.size() < 1) {
            QMessageBox::warning(this, tr("错误"), tr("文件数据与目标类型不匹配。"));
            return;
        }
        QList<FreqTableConfig> list;
        for (const auto &fields : csvData) {
            if (fields.size() < 1)
                continue;
            FreqTableConfig row;
            row.Freq = fields[0].toDouble() * 1e6;
            list.append(row);
        }
        newItem.name = newTableName;
        newItem.type = ParamTableKind::Frequency;
        m_pendingSelectionName = newTableName;
        if (!DataManager::instance()->addParameterTable(newItem)) {
            qWarning() << "add ParameterTable failed！ itemName:" << newItem.name;
            break;
        }
        saveOk = DataManager::instance()->saveFreqTable(newItem.id, newTableName, list);
        break;
    }

    default:
        QMessageBox::warning(this, tr("错误"), tr("不支持导入此类型的表格。"));
        return;
    }

    if (saveOk) {
        m_pendingSelectionName = newTableName;
        QMessageBox::information(this, tr("成功"), tr("文件已成功导入并创建为新的表格 '%1'。").arg(newTableName));
    } else {
        QMessageBox::critical(this, tr("失败"), tr("保存导入的数据到数据库时发生错误。"));
    }
}

/**
 * @brief ParameterBrowserWidget::onTransSourceUnitHeaderChanged
 * @details 换能器源单位下拉框变化时更新模型。
 * @param index 当前索引。
 */
void ParameterBrowserWidget::onTransSourceUnitHeaderChanged(int index)
{
    Q_UNUSED(index)
    if (!m_transSourceUnitHeaderCombo || !m_ctx.valid || m_ctx.kind != ParamTableKind::Transducer) {
        return;
    }
    // 直接使用新的 setter 方法
    m_modelSimple->setTransducerSourceUnit(m_transSourceUnitHeaderCombo->currentText());
}

/**
 * @brief ParameterBrowserWidget::onTransTargetUnitHeaderChanged
 * @details 换能器目标单位下拉框变化时更新模型。
 * @param index 当前索引。
 */
void ParameterBrowserWidget::onTransTargetUnitHeaderChanged(int index)
{
    Q_UNUSED(index)
    if (!m_transTargetUnitHeaderCombo || !m_ctx.valid || m_ctx.kind != ParamTableKind::Transducer) {
        return;
    }
    // 直接使用新的 setter 方法
    m_modelSimple->setTransducerTargetUnit(m_transTargetUnitHeaderCombo->currentText());
}
